package cn.kailangtu.dataspot;

import android.content.Intent;
import android.os.Build;
import android.os.Environment;
import android.os.SystemClock;
import android.util.Log;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.litepal.LitePal;
import org.litepal.LitePalApplication;

import java.io.File;
import java.io.IOException;

import cn.kailangtu.commonevents.eventEntity.AutoDataRefreshEvent;
import cn.kailangtu.commonevents.eventEntity.ControlsClickEvent;
import cn.kailangtu.commonevents.eventEntity.KeyboardNumberInputEvent;
import cn.kailangtu.commonevents.eventEntity.OnFragmentChangeEvent;
import cn.kailangtu.commonevents.eventEntity.TimeoutEvent;
import cn.kailangtu.commonevents.eventEntity.WriteDataToMachineEvent;
import cn.kailangtu.commontools.APPSPUtils;
import cn.kailangtu.commontools.AppInstallUtil;
import cn.kailangtu.commontools.AppUtils;
import cn.kailangtu.commontools.AppVariable;
import cn.kailangtu.commontools.CommonUtils;
import cn.kailangtu.commontools.ConnectUtils;
import cn.kailangtu.commontools.EthernetUtils;
import cn.kailangtu.commontools.Loggers;
import cn.kailangtu.commontools.TextFileIO;
import cn.kailangtu.commontools.socket.SocketClient;
import cn.kailangtu.dataspot.data.consts.ControlEventValues;
import cn.kailangtu.dataspot.data.status.ConnectStatus;
import cn.kailangtu.dataspot.db.ExceptionLogEntity;
import cn.kailangtu.dataspot.db.NewTotalDataEntity;
import cn.kailangtu.dataspot.db.OptionLogEntity;
import cn.kailangtu.dataspot.db.SwitchLogEntity;
import cn.kailangtu.dataspot.services.BootService;
import cn.kailangtu.dataspot.services.KillSelfService;
import cn.kailangtu.dataspot.services.SocketService;
import cn.kailangtu.dataspot.services.WatchdogService;
import cn.kailangtu.dataspot.tasks.BaseTask;
import cn.kailangtu.dataspot.tasks.PLCTask;
import cn.kailangtu.dataspot.tasks.TaskManager;
import cn.kailangtu.dataspot.update.AppManagerUtils;
import cn.kailangtu.modbus.ModbusSlave;
import cn.kailangtu.serialutils.api.DIManager;
import cn.kailangtu.serialutils.api.GpioUtils;
import cn.kailangtu.serialutils.api.ReceiveLogMessageListenerV2;
import cn.kailangtu.serialutils.api.ReceiveMsgListenerV2;
import cn.kailangtu.serialutils.api.SerialPort485Manager;
import cn.kailangtu.serialutils.api.SerialPortApi;
import cn.kailangtu.serialutils.modbus.modbusUtil;

public class DataSpotApplication extends LitePalApplication {

    public static boolean isOpen = false;


    private void buildExceptionLogForTest() {
        LitePal.deleteAll(ExceptionLogEntity.class);

    }

    @Override
    public void onCreate() {
        super.onCreate();

        AppUtils.getInstance().setContext(this);
        AppUtils.getInstance().setApplication(this);
        AppUtils.getInstance().startBzAppIsTopThread();
        EventBus.getDefault().register(this);
        APPSPUtils.getInstance().init(getApplicationContext());

        EthernetUtils.resetIp();
        AppBasicMethod.getInstance().setContext(this);
        AppBasicMethod.getInstance().setApplication(this);
        AppBasicMethod.getInstance().startBzAppIsTopThread();


        CrashHandler.active(this);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(new Intent(this, BootService.class));
            startForegroundService(new Intent(this, SocketService.class));

                //startForegroundService(new Intent(this, WatchdogService.class));

        } else {
            Intent intent = new Intent(getApplicationContext(), BootService.class);
            startService(intent);
            startService(new Intent(this, SocketService.class));

            //startService(new Intent(this, WatchdogService.class));

        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                AppWork();
            }
        }).start();

        SerialPortApi.getInstance().Init(DataSpotApplication.this, new ReceiveLogMessageListenerV2() {
            @Override
            public void onLogMessage(String msg) {
                Loggers.hardwareInfo(msg);
            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                DIManager.getInstance().initListener((itemNo, actionCode, actionMsg) -> {
                   Log.d("DataSpotApplication==>","收到DI:" + itemNo + "|" + actionCode + "|" + actionMsg);
                    if (actionCode == 1) {
                        EventBus.getDefault().post(new ControlsClickEvent(itemNo + 1));
                        status.resetLastOptionTime();
                    }
                });
            }
        }).start();

        TaskManager.getInstance().openAllTask();

        //serialPortSpy();
        optionSpy();

        if(AppVariable.platform_version == 450){

            SerialPort485Manager.getInstance().initSerialPort();
            SerialPort485Manager.getInstance().setComHongwaiListener(new ReceiveMsgListenerV2() {
                @Override
                public void onReceiveData(byte[] data) {
                    Log.d("SHOOTLEE_HONGWAI","进来了");
                    String hongweiCmd = CommonUtils.ByteArrayToHexString(data);
                    switch(hongweiCmd){
                        case "00FF5A":
                            byte[] currentCmd = modbusUtil.writeToOne(1, CommonUtils.int2ByteArray(3595),
                                    CommonUtils.int2ByteArray(1));
                            BaseTask.addNewPLCCommand(currentCmd);
                            break;
                        case "00FF1C":
                            EventBus.getDefault().post(new ControlsClickEvent(ControlEventValues.ENTRY));
                            status.resetLastOptionTime();
                            break;
                        case "00FF18":
                            EventBus.getDefault().post(new ControlsClickEvent(ControlEventValues.LEFT));
                            status.resetLastOptionTime();
                            break;
                        case "00FF52":
                            EventBus.getDefault().post(new ControlsClickEvent(ControlEventValues.RIGHT));
                            status.resetLastOptionTime();
                            break;
                        case "00FF45":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("1"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF46":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("2"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF47":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("3"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF44":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("4"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF40":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("5"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF43":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("6"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF07":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("7"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF15":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("8"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF09":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("9"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF16":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("."));
                            status.resetLastOptionTime();
                            break;
                        case "00FF19":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("0"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF0D":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("*"));
                            status.resetLastOptionTime();
                            break;
                        case "00FF08":
                            EventBus.getDefault().post(new KeyboardNumberInputEvent("BACK"));
                            status.resetLastOptionTime();
                            break;

                    }
                }
            });
            GpioUtils.getInstance().beginSpy();
        }
        else {
            SerialPortApi.getInstance().openSerialPortV2("", 256000, 0);
        }

        //TotalData.Test(7);
        //TotalData.test2();
       // testModbus();

        //TotalData.testnew();

        AppBasicMethod.getInstance().processExceptionLog();
        deleteLog();

        String startCmd = "";
        new TextFileIO(this).writeToFile(Environment.getExternalStorageDirectory().getAbsolutePath(),"app_start.txt","cn.kailangtu.dataspot/.activify.SplashActivity");

        AppInstallUtil.toSpy();

        autoViewRefresh();

        ipSpy();
       // testSokcet();



        AppManagerUtils.toSpy();

    }


    private void testModbus()
    {
        new Thread(new Runnable() {
            @Override
            public void run() {

                ModbusSlave.setTestData();
                /*
                byte[] receive =  ModbusSlave.execute("01100087000204050607085912");
                Log.d("MODBUS",CommonUtils.ByteArrayToHexString(receive));
                SystemClock.sleep(2000);
                receive =   ModbusSlave.execute("0103008700027422");
                Log.d("MODBUS",CommonUtils.ByteArrayToHexString(receive));

                 */
                byte[] receive = ModbusSlave.executeTcp("D10200000006010600320064");
               // byte[] receive = ModbusSlave.executeTcp("123400000006010600641632");
                if(receive != null) {
                    Log.d("SOCKETSOCKETMODBUS", CommonUtils.ByteArrayToHexString(receive));
                }
                SystemClock.sleep(1000);
                receive = ModbusSlave.executeTcp("234500000006010300000064");
                if(receive != null) {
                    Log.d("SOCKETSOCKETMODBUS", CommonUtils.ByteArrayToHexString(receive));
                }

            }
        }).start();
    }


    private void AppWork() {
        int connectIndex = 0;

        while (true) {

            connectIndex++;
            if (connectIndex >= 100) {
                connectIndex = 0;
                ConnectUtils.getNetworkInfo(this);
                ConnectStatus.setBluetoothConnected(ConnectUtils.isBluetoothConnected());
                ConnectStatus.setEthernetConnected(ConnectUtils.isEthernetConnected());
                ConnectStatus.setMobileConnected(ConnectUtils.isMobileConnected());
                ConnectStatus.setWifiConnected(ConnectUtils.isWifiConnected());

                //UsbUtils.getUserDevices(this);
                //ConnectStatus.setUsbConnected(UsbUtils.isUsbConnected());
            }
            SystemClock.sleep(50);
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(WriteDataToMachineEvent event) {
       byte[] currentCmd = modbusUtil.writeToOne(event.getAddress(), CommonUtils.int2ByteArray(event.getStorage()),
                CommonUtils.int2ByteArray(event.getValue()));
       //byte[] readCmd = modbusUtil.read(event.getAddress(),CommonUtils.int2ByteArray(event.getStorage()),new byte[]{0x00,0x01});
       BaseTask.addNewPLCCommand(currentCmd);
    }



    private void serialPortSpy()
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    if (System.currentTimeMillis() - SerialPortApi.getInstance().getLastReceiveTime() > 10000) {
                        SerialPortApi.getInstance().setLastReceiveTime(System.currentTimeMillis());

                        Intent intent = new Intent(DataSpotApplication.getContext(), KillSelfService.class);
                        intent.putExtra("PackageName", getPackageName());
                        intent.putExtra("Delayed", 500);
                        startService(intent);
                        SystemClock.sleep(1000);
                    }
                    SystemClock.sleep(1000);
                }

            }
        }).start();
    }

    private void optionSpy()
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                int timeOver = 1000 * 60 *2;
                while(true){
                    SystemClock.sleep(1000);
                    if( (System.currentTimeMillis() - status.lastOptionTime) > timeOver){
                        status.resetLastOptionTime();
                        //每两分钟请求一次回到主页面，各当前页面根据需要决定返回不返回
                        EventBus.getDefault().post(new OnFragmentChangeEvent(R.layout.fragment_real_picture));
                        EventBus.getDefault().post(new OnFragmentChangeEvent(R.layout.fragment_real_picture_low));
                        EventBus.getDefault().post(new TimeoutEvent());
                    }
                }
            }
        }).start();
    }

    private void deleteLog()
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                int eLog =   LitePal.count(ExceptionLogEntity.class);
                int sLog = LitePal.count(SwitchLogEntity.class);
                int oLog = LitePal.count(OptionLogEntity.class);
                if(eLog > 5000)
                {
                    int id = LitePal.max(ExceptionLogEntity.class, "logNumber", Integer.class);
                    LitePal.deleteAll(ExceptionLogEntity.class,"logNumber < "+(id - 2000));
                }
                if(sLog  > 5000)
                {
                    int id = LitePal.max(SwitchLogEntity.class, "logNumber", Integer.class);
                    LitePal.deleteAll(SwitchLogEntity.class,"logNumber < "+(id - 2000));
                }
                if(oLog > 5000){
                    int id = LitePal.max(OptionLogEntity.class, "logNumber", Integer.class);
                    LitePal.deleteAll(OptionLogEntity.class,"logNumber < "+(id - 2000));
                }


                int count = LitePal.count(NewTotalDataEntity.class);
                Log.d("ADDADDDATA","总共找到："+count+"条");
                //删除101天之前的数据
                count =  LitePal.deleteAll(NewTotalDataEntity.class,"createTime < " + (System.currentTimeMillis() - 3600 * 24 * 101 * 1000 ));
                //count =  LitePal.deleteAll(NewTotalDataEntity.class,"createTime > 0 ");
                Log.d("ADDADDDATA","删除了："+count+"条");
            }
        }).start();

    }

    private void autoViewRefresh()
    {
        new Thread(new Runnable() {
            @Override
            public void run() {

                while(true){
                    EventBus.getDefault().post(new AutoDataRefreshEvent());
                    SystemClock.sleep(300);
                }

            }
        }).start();
    }

    private void ipSpy()
    {
        new Thread(new Runnable() {
            @Override
            public void run() {


                boolean isOk = true;
                SystemClock.sleep(10000);
                while(true) {
                    String eth0 =  EthernetUtils.getEthernetIp("eth0");
                    String eth1 = EthernetUtils.getEthernetIp("eth1");

                    /*
                    if(!APPSPUtils.getInstance().getLocalIpEth0().equals(eth0))
                    {
                        EthernetUtils.resetIpEth0();
                    }
                    if(!APPSPUtils.getInstance().getLocalIpEth1().equals(eth1))
                    {
                        EthernetUtils.resetIpEth1();
                    }

                     */


                    if(APPSPUtils.getInstance().getLocalIpEth0().equals(eth0) && APPSPUtils.getInstance().getLocalIpEth1().equals(eth1))
                    {
                        isOk = true;
                    }
                    else{
                        isOk = false;
                    }

                    Log.d("SHOOTLEE_IPSPY","0:"+eth0+"  ||| 1:"+eth1);
                    if (!isOk) {
                        EthernetUtils.resetIp();
                        SystemClock.sleep(2000);
                    }



                    SystemClock.sleep(5000);
                }

            }
        }).start();

    }

    private SocketClient socketClient;
    byte[] receiveData;
    private void testSokcet() {

        socketClient = new SocketClient("127.0.0.1", 3000);
        socketClient.setSocketListener(new SocketClient.SocketListener() {
            @Override
            public void onMessageReceived(byte[] data) {
                //Log.d("SHOOTLEESOCKET","收到数据:"+CommonUtils.ByteArrayToHexString(data));
                receiveData = data;
            }

            @Override
            public void onStatusChanged(boolean isConnected) {

            }
        });

        socketClient.connect();


        new Thread(new Runnable() {
            @Override
            public void run() {
                byte[] sendBytes = new byte[]{
                        0x00 ,0x01 ,0x00 ,0x00 ,0x00 ,0x06 ,0x01 ,0x03 ,0x00 ,0x00 ,0x00 ,0x55
                };
                SystemClock.sleep(5000);
                while(true)
                {
                    long start = System.currentTimeMillis();
                    byte[] result =  sendAndReceive(sendBytes);
                    long end = System.currentTimeMillis();
                    if(result != null && result.length>0)
                    {
                        Log.d("SHOOTLEESOCKET","读到数据："+CommonUtils.ByteArrayToHexString(result));
                    }
                    else
                    {
                        Log.d("SHOOTLEESOCKET","未读到数据");
                    }
                    Log.d("SHOOTLEESOCKET","间隔："+(end-start)+"ms");
                    SystemClock.sleep(5);
                }
            }
        }).start();
    }

    public byte[] sendAndReceive(byte[] sendData)
    {
        try {
            // 发送示例数据
            receiveData = null;
            socketClient.sendData(sendData);
            int index = 0;
            while( index < 100)
            {
                if(receiveData != null && receiveData.length>0) {
                    return receiveData.clone();
                }
                SystemClock.sleep(5);
                index++;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}